﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using CoolCode.Reflection;

namespace CoolCode.Xml
{
    public class XmlManager
    {
        public static XElement Load(string fileName)
        {
            return XElement.Load(fileName);
        }

        public static string ReadToString(string fileName)
        {
            XElement xe = Load(fileName);
            if (xe != null)
                return xe.ToString();
            return string.Empty;
        }

        public static List<XElement> ReadHeader(string fileName, string headerName)
        {
            XElement xmlFile = Load(fileName);
            return xmlFile.Elements(headerName).ToList();
        }

        public static List<XElement> ReadContent(XElement head, string contentName)
        {
            var xml = head.Elements(contentName);
            return xml.ToList();
        }

        public static List<XElement> ReadXML(string fileName, string header)
        {
            XElement xmlFile = XElement.Load(fileName);
            return xmlFile.Element(header).Elements().ToList();
        }

        public static DataSet XmlToDataSet(string xmlText)
        {
            DataSet result = new DataSet();
            // System.IO.StringReader sr=;
            result.ReadXmlSchema(new System.IO.StringReader(xmlText));
            foreach (DataTable dt in result.Tables)
                dt.BeginLoadData();//'加载架构

            result.ReadXml(new System.IO.StringReader(xmlText), XmlReadMode.IgnoreSchema);
            foreach (DataTable dt in result.Tables)
                dt.EndLoadData();
            return result;
        }

        public static System.IO.MemoryStream ReadXML(DataSet ds)
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            ds.WriteXml(ms, XmlWriteMode.WriteSchema);
            return ms;
        }

        public static bool Insert<T>(XElement root, T t) where T : class
        {
            if (t == null) return false;
            var className = BLReflection.GetClassName<T>();
            var dict = BLReflection.ToDictionary<T>(t);

            XElement xe = new XElement(className);
            foreach (var d in dict)
                xe.Add(new XElement(d.Key, d.Value));
            root.Add(xe);
            return true;
        }

        public static bool Insert<T>(XElement root, List<T> list) where T : class
        {
            if (list == null) return false;
            var className = BLReflection.GetClassName<T>();
            foreach (var t in list)
            {
                var dict = BLReflection.ToDictionary<T>(t);

                XElement xe = new XElement(className);
                foreach (var d in dict)
                    xe.Add(new XElement(d.Key, d.Value));
                root.Add(xe);
            }
            return true;
        }

        public static bool Insert<T>(string xmlFile, T t) where T : class
        {
            var root = Load(xmlFile);
            bool result = Insert<T>(root, t);
            root.Save(xmlFile);
            return result;
        }

        public static bool Insert<T>(string xmlFile, List<T> list) where T : class
        {
            var root = Load(xmlFile);
            bool result = Insert<T>(root, list);
            root.Save(xmlFile);
            return result;
        }

        public static List<T> Load<T>(XElement root) where T : class, new()
        {
            List<T> result = new List<T>();
            var className = BLReflection.GetClassName<T>();
            var xList = root.Elements(className);
            foreach (var x in xList)
            {
                T t = new T();
                var ps = t.GetType().GetProperties();
                foreach (var p in ps)
                {
                    Type type = p.PropertyType;
                    object value = null;
                    if (type.Name == typeof(string).Name)
                        value = x.Element(p.Name).Value;
                    else
                        value = BLReflection.Parse(type, x.Element(p.Name).Value);
                    p.SetValue(t, value, null);
                }
                result.Add(t);
            }
            return result;
        }

        public static List<T> Load<T>(string xmlFile) where T : class, new()
        {
            var root = Load(xmlFile);
            return Load<T>(root);
        }

    }
}
